﻿using UnityEngine;

namespace Framework
{
    public class StaticBlockRender : IRender
    {
        enum Direction
        {
            Right,
            Left,
            Up,
            Down,
            Forward,
            Backward
        }

        public void RenderBlock(Vector3Int pos, Chunk chunk, StaticBlockChunkRender.MeshCreatorContex contex)
        {
            //extend chunk to save side info ,of course not work so good 
            if (pos.x < Chunk.size.x && chunk.At(pos + Vector3Int.right) == BlockType.Empty & chunk.At(pos) != BlockType.Empty)
            {
                CreatQuad(pos, Direction.Right, contex, contex.config.texture.TextureUV(1));
            }
            if (pos.x > 0 && chunk.At(pos + Vector3Int.left) == BlockType.Empty & chunk.At(pos) != BlockType.Empty)
            {
                CreatQuad(pos, Direction.Left, contex, contex.config.texture.TextureUV(1));
            }
            if (pos.y < Chunk.size.y - 1 && chunk.At(pos + Vector3Int.up) == BlockType.Empty & chunk.At(pos) != BlockType.Empty)
            {
                CreatQuad(pos, Direction.Up, contex, contex.config.texture.TextureUV(2));
            }
            if (pos.y > 0 && chunk.At(pos + Vector3Int.down) == BlockType.Empty & chunk.At(pos) != BlockType.Empty)
            {
                CreatQuad(pos, Direction.Down, contex, contex.config.texture.TextureUV(0));
            }
            if (pos.z < Chunk.size.z && chunk.At(pos + Vector3Int.forward) == BlockType.Empty & chunk.At(pos) != BlockType.Empty)
            {
                CreatQuad(pos, Direction.Forward, contex, contex.config.texture.TextureUV(1));
            }
            if (pos.z > 0 && chunk.At(pos + Vector3Int.back) == BlockType.Empty & chunk.At(pos) != BlockType.Empty)
            {
                CreatQuad(pos, Direction.Backward, contex, contex.config.texture.TextureUV(1));
            }

        }

        private static void CreatQuad(Vector3Int coord, Direction direction, StaticBlockChunkRender.MeshCreatorContex contex, (Vector2, Vector2) uv)
        {
            int baseIndex = contex.verts.Count;
            switch (direction)
            {
                case Direction.Right:
                    contex.verts.Add(coord + new Vector3(1, 0, 1));
                    contex.verts.Add(coord + new Vector3(1, 0, 0));
                    contex.verts.Add(coord + new Vector3(1, 1, 0));
                    contex.verts.Add(coord + new Vector3(1, 1, 1));
                    break;
                case Direction.Left:
                    contex.verts.Add(coord + new Vector3(0, 0, 0));
                    contex.verts.Add(coord + new Vector3(0, 0, 1));
                    contex.verts.Add(coord + new Vector3(0, 1, 1));
                    contex.verts.Add(coord + new Vector3(0, 1, 0));
                    break;
                case Direction.Up:
                    contex.verts.Add(coord + new Vector3(0, 1, 0));
                    contex.verts.Add(coord + new Vector3(0, 1, 1));
                    contex.verts.Add(coord + new Vector3(1, 1, 1));
                    contex.verts.Add(coord + new Vector3(1, 1, 0));
                    break;
                case Direction.Down:
                    contex.verts.Add(coord + new Vector3(0, 0, 0));
                    contex.verts.Add(coord + new Vector3(1, 0, 0));
                    contex.verts.Add(coord + new Vector3(1, 0, 1));
                    contex.verts.Add(coord + new Vector3(0, 0, 1));
                    break;
                case Direction.Forward:
                    contex.verts.Add(coord + new Vector3(0, 0, 1));
                    contex.verts.Add(coord + new Vector3(1, 0, 1));
                    contex.verts.Add(coord + new Vector3(1, 1, 1));
                    contex.verts.Add(coord + new Vector3(0, 1, 1));
                    break;
                case Direction.Backward:
                    contex.verts.Add(coord + new Vector3(0, 0, 0));
                    contex.verts.Add(coord + new Vector3(0, 1, 0));
                    contex.verts.Add(coord + new Vector3(1, 1, 0));
                    contex.verts.Add(coord + new Vector3(1, 0, 0));
                    break;
            }
            contex.uvs.Add(uv.Item1);
            contex.uvs.Add(new Vector2(uv.Item2.x, uv.Item1.y));
            contex.uvs.Add(uv.Item2);
            contex.uvs.Add(new Vector2(uv.Item1.x, uv.Item2.y));
            contex.indices.AddRange(new int[] { baseIndex + 0, baseIndex + 1, baseIndex + 2, baseIndex + 3 });
        }
    }
}